# Одинокий спринт

## Зачем?

Никогда еще мне не приходилось работать спринтами и мне стало интересно каково это. Все получилось спонтанно: прилетела задача реализации новой акции по доставке, нужно было доделывать дипломную работу по курсам Flutter, а по проекту, который я неспешно пилил в своё удовольствие вдруг возникли горящие сроки.

Я подумал, что если объединю эти задачи в спринт и сфокусируюсь на них, то у меня все получится.

## Описание проектов и план на спринт

Итак, спринт стартует 29.03.2021 (понедельник) и завершится 14.04.2021 (среда). Именно 14 апреля - срок запуска акции.

### Flutter & Dart: Gallery app for unsplash.com

Эта задача возникла как результат прохождения курсов по Flutter. Сам курс проходил с косяками в организации и после нескольких уроков перестали давать практику - голая теория, а в конце курса решили всю практику уместить в итоговую квалификационную работу. Сначала, я не очень настроен был выполнять работу, тем более, что курс ничего нового мне не открыл в мире Flutter. Но в итоге все-же приступил к заданию.

[**Gallery app for unsplash.com**](https://github.com/oreshkanet/skill_branch_flutter) - это приложение для просмотра контента с фотостока unsplash.com.

Основной функционал приложения: 

- просмотр новых фотографий
- поиск фотографий 
- просмотр связанных фотографий 
- просмотр профиля автора фотографии 
- авторизация и просмотр своего профиля 
- возможность поставить like фотографии 

В процессе прохождения курса в качестве домашних заданий я уже реализовал часть функционала и за спринт планирую выполнить только требования задания в функциональной части мобильного приложения (красивый UI конечно важен, но за спринт не успеть, а со стилями и анимациями я уже поработал). В итоге я должен получить полностью рабочее мобильное приложение в рамках функционала, описанного в ТЗ (ссылку на ТЗ не могу оставить, поскольку является частью закрытого курса).

### 1С: Предприятие 8: Акция на доставку заказов

Компания [КуулКлевер](https://www.linkedin.com/company/coolclever/?lipi=urn%3Ali%3Apage%3Ad_flagship3_pulse_read%3Boc3IDOk1TryMllwV4zfoWw%3D%3D) (сеть магазинов МясновЪ, Отдохни) предоставляет покупателям возможность оформить заказ с доставкой (и это не реклама!). Передо мной поставлена задача реализации возможности настройки различных акций на стоимость доставки в зависимости от состава заказа, суммы заказа, расстояния доставки, сегмента покупателя. При этом должны действовать ограничения на количество доставок со скидкой.

Акция будет рассчитываться в сервисе на 1С:Предприятие 8 - процессинге Лояльности (о нём я писал уже [здесь](https://github.com/oreshkanet/articles/blob/master/loyalty_processing_1c.md)).

Обычно, всевозможные виды акций отлично вписывались в стройную логику расчета лояльности по заказу. А в этой акции было несколько условий, которые не позволяли применять те же подходы к ее реализации.

Кроме того, акция уже должна работать 14 апреля - это и есть цель спринта по этой задаче.

### GoLang: Сервис электронной очереди

В магазинах [КуулКлевер](https://www.linkedin.com/company/coolclever/?lipi=urn%3Ali%3Apage%3Ad_flagship3_pulse_read%3Boc3IDOk1TryMllwV4zfoWw%3D%3D) есть электронная очередь (ЭЛО): нажал на кнопку -> получил талон с номером -> ждешь когда на дисплее отобразится твой номер.

Все началось с того, что сняли с производства кнопки вызова из очереди. Эта кнопка стоит у продавца и при ее нажатии на табло отображается следующий в очереди номер талончика.

Поэтому было предложено реализовать собственный сервис управления очередью - ЭЛО v2. Сервис должен уметь работать с принтером талончиков, табло, а также кнопкой вызова из очереди (для поддержки) по протоколу TCP. Вместо физической кнопки вызова нужно реализовать метод в API, который будет дергать кассовая программа.

---

# Неделя первая

## 29.03.2021, понедельник, 05:30 - 18:00

### Flutter: Gallery app

*Утро, я на работе и начинаю работу над профилем пользователя.*

По ТЗ я должен сделать одинаковые экраны для просмотра как своего профиля, так и профиля других пользователей. Документация по API говорит, что структура JSON отличается, но не критично. Сливаю оба в один общий JSON и пишу на его базе общую модель.

В repository и providers добавляю новые методы для получения своего профиля и профиля по имени пользователя.

Далее Bloc. С момента обучения вышла новая версия Bloc 6. Изучаю материалы и документацию. На основании полученных знаний пишу нужные классы для реализации этого паттерна (event, state, bloc) и сразу закладываю возможность работы с двумя типами профиля: me, user.

Пришло время экрана для просмотра своего профиля. Создаю виджет profile, его буду использовать на двух разных экранах. И помещаю виджет на экран profileScreen.

В итоге получил рабочую страницу своего профиля.

*Пришли коллеги, со всеми нужно пообщаться и попить кофе. Делаем перерыв.*

### 1С: Акция на доставку заказов

*Утренний стендап с шефом, раздаю задачи рабочей группе и уединяюсь кодить акцию.*

Акция должна применять скидку на доставку, а это значит, что в запросах на расчет Лояльности появляется детальная информация о доставке.

Оказалось что в ядро процессинга нужно добавить новую структуру для хранения данных о доставке. А это затронет все, абсолютно все запросы. Придется прогонять массовый тест... Ну а пока кодинг.

Создаём новый модуль, пишем процедуру инициализации структуры delivery и аккуратненько впиливаем ее в ядро. Во всех нужных запросах структура должна заполняться и возвращаться в ответе.

Посмотрел на модуль расчета Лояльности по корзине заказа. Понял что хочу “отрефачить” его, поскольку в нем есть много старого и ненужного кода.

*В итоге Процессинг научился получать, обрабатывать и возвращать доставку (правда пока без скидок). Готовлю релиз, обновляю stage, прогоняю тесты. Все ок, выкатываю в production, чтобы разработчики других групп уже могли работать с новой структурой в запросах.*

### Go: Сервис ЭЛО

*Осталось пара часов рабочего времени и сегодня хочу научить сервис работать с базой Sqlite.*

Для начала описываю модель для хранения данных очереди. Далее создаю структуру для репозитория, прописываю подключение к базе данных и отключение от нее, создание таблицы, запросы на запись текущего и чтение сохраненного состояния очереди.

Поскольку в файле main.go уже есть тестовый код работы с принтером ЭЛО, впиливаю в него чтение и запись очереди через созданный репозиторий. 

*Запускаю сервис в отладке и иду домой.*

---

## 30.03.2021, вторник, 06:00 - 18:00

### Flutter: Gallery app

*Снова утро. Продолжаю работать с профилем. Сегодня делаю скрин для профиля других пользователей сервиса. Он должен открываться при нажатии на аватар автора фотографии.*

Создаю класс UserProfileScreen для скрина и использую в нем созданный вчера виджет profile. Добавляю Hero-анимацию при открытии профиля пользователя, чтобы было красиво (зачеркнуть) соответствовало ТЗ.

Сделал AppBar для скринов профиля пользователя в соответствии с дизайном.

На странице с профилем должны быть вкладки с одинаковой версткой: мои фотографии, мои лайки, мои коллекции. Поэтому оформил их как отдельный виджет и вывел в табах на скрине профиля (пока пустые, данные нужно получать из api).

### Go: Сервис ЭЛО

Начинаю освоение "Чистой архитектуры". Посмотрел видео одного блогера, в котором он рассказывает свое видение чистой архитектуры в проектах на Go. Не до конца понятно (примеров кода к видео нет), но идея понравилась. Пробую применить.

Начинаю с принтера ЭЛО - пробую оформить как отдельный пакет транспортного уровня.

### 1С: Акция на доставку заказов

Поскольку Процессинг находится на стадии модернизации всей системы акции, в нем есть 2 варианта реализации акций: старая и новая. Поскольку времени мало было принято решение пилить в старой логике.

Начинаю разработку основной процедуры расчета акции. Но вскоре понимаю, что некоторые условия акции нереализуемы в старой логике. Печально. Придется делать в новой логике. Нужно взять паузу и обдумать.

---

## 31.03.2021, среда, 06:00 - 18:00

### Flutter: Gallery app

*6-утренний кофе помогает взбодриться. Начинаю разборки с API Unsplash для получения списка фото пользователя, его лайков и коллекций.*

Добавляю в репозиторий методы для получения списка фото пользователя, а также лайков и коллекций.

Обращаться к API из виджетов буду используя Bloc-архитектуру. Реализовал нужные классы Bloc для получения списка фото. Завтра буду впиливать Bloc для фото в виджет Profile.

Сборка приложения, тест, кофе с коллегами.

### 1С: Акция на доставку заказов

Случайно забрёл на совещание с бизнесом. Выяснилось некоторые правки к ТЗ по акциям. Придется переосмыслить концепцию более глобально.

Сначала посидел в одиночестве, подумал. А затем и руководитель разработки присоединился. Придумали рабочую логику работы акции и схему взаимодействия сервисов.

### Go: Сервис ЭЛО

Перелопатил весь проект, попилил на пакеты, но сервис до сих пор работает. Круто.

---

## 01.04.2021, четверг, 06:00 - 18:00

### Flutter: Gallery app

*Очередное супер-раннее утро. Работа. Flutter.*

Затаскиваю в ProfileBloc получение 3х списков фотографий: фото пользователя, лайки пользователя, коллекции. Коллекции пользователя - это другая модель, для которой нужен отдельный класс Collection, а пока работаю с ним как со списком фото.

Добавляю в событие загрузки профиля получение всех 3х списков, а запросы отправляю параллельно в Future.wait().

*Собираю приложение, тестирую и иду пить кофе с коллегами.*

### 1С: Акция на доставку заказов

Новый endpoint в сервисе (подтверждение оформления заказа). Поскольку меняется схема запросов между сервисами по интернет-заказам, придется некоторые endpoint'ы подправить и добавить новых для обработки различных состояний заказа. Добавляю новые модули под каждый тип запроса, записываю состояние заказа в каждом и в некоторых вызываю расчет акций.

Прогнал тестовые кейсы - вроде ничего не сломалось. Завтра подготовлю релиз и накачу на прод.

### Go: Сервис ЭЛО

Перелопатил всю структуру проекта (в смысле раскидал файлики по папкам). Сделал "чистым" пакет repository.

*Сегодня было много общения по поводу других проектов, но и этому проекту удалось выделить время.*

---

## 02.04.2021, пятница, 11:00 - 18:00


### 1С: Акция на доставку заказов

Собираю конфигурацию для обновления и накатываю на stage. Прогоняю еще раз тесты и раскатываю в прод, но только на ноды, обрабатывающие сервисные и асинхронные запросы (пятница - опасно!). Помониторил логи и метрики, все гуд.

Хитрая акция должна проверять условия в одном запросе (при оформлении заказа), а применять скидки в другом (перед оплатой покупателем). А значит создаю таблички в базе данных для хранения результатов расчета акции. Добавляю в процессинг функции записи и чтения для них. Хитрую логику пилить буду позже, а пока нужны таблички, чтобы другие разработчики уже могли начинать с ними работать.

Выкатываю в тестовое окружение и прогоняю цепочку запросов по интернет-заказам. 

*Все работает, а значит в понедельник можно и уже переходить к программированию самой акции.*

---

# Неделя вторая

## 05.04.2021, понедельник, 06:00 - 18:00

### Flutter: Gallery app

*Понедельник и я полон сил. На часах 6:00. Кофе и кодинг.*

Добавляю модель для Collections с методами для десериализации объекта из json. Параллельно отрефакторил все остальные модели. Поудалял лишние свойства из классов, которые не используются.

Теперь корректирую ProfileBloc под модель Collections и тестирую виджет целиком. Получается, что при то загрузки профиля вместе с ним сразу загружаются и все списки фотографий.

Понял, что списки фотографий не круто хранить в ProlfileBloc, поэтому их надо вытаскивать в отдельный PhotoListBloc. Теперь под каждый список создается свой экземпляр класса Bloc, которым можно управлять независимо от других (обновлять, догружать, очищать данные).

Переписываю виджет для вывода сетки фоток под использование нового Bloc-класса.

*Собираю проект, запускаю в эмуляторе и тестирую. Все работает. Традиционный кофе с коллегами...*

### 1С: Акция на доставку заказов

*Сроки горят, акция ждёт...*

Приступаю к программированию нового типа акции. Акцию буду делать как можно более универсальной, потому как финальные условия акции обычно известно перед стартом. А значит впиливаю поддержку сегментов покупателей, возможность работы по сертификатам, и все числовые параметры акции переношу в настройки.

Сначала программирую проверку условий акции, в соответствии с настройками. А затем и функцию применения скидки, если условия выполнены. Вставляю результаты акции в JSON ответа.

*Акция уже работает, правда есть ещё несколько моментов, которые не соответствуют ТЗ, но зато уже можно проводить какие-то интеграционные тесты и смотреть как же акция отображается на фронтах.*

---

## 06.04.2021, вторник, 06:00 - 18:00

### Flutter: Gallery app

*6 утра и кофе, а значит Flutter меня ждёт.*

Продолжаю работать со скрином профиля. Делаю отдельный виджет CollectionsList для вывода последнего Tab - коллекции пользователя. Немножко рефакторинга и профиль готов.

По нажатию на коллекцию должен открываться экран с фотографиями этой коллекции. А значит создаю новый скрин CollectionPhoto, на котором в виде сетки выводятся фотографии.

Расширяю repository методом получения фотографий по коллекции, чтобы было что выводить в виджете.

*Тест... Кофе... Ну вы поняли...*

### 1С: Акция на доставку заказов

Добавляю ограничение на количество заказов, в которых может применяться скидка для одного покупателя. Это один из параметров акции. Ограничение проверяю с  помощью таблички в базе MS SQL, запись в которую я впилил ранее.

### Node.JS: Электронные чеки

*Срочная задача - добавить банковский СЛИП в электронную форму чека лояльности.*

Открываю проект микросервиса на Node JS, добавляю обработку входящей новой структуры с данными и вывожу ее в шаблон.

Тестирую и засылаю новый вариант электронного чека на согласование. Получаю "ОК" и накатываю новую версию сервиса в бой.

### 1С: Акция на доставку заказов

*Возвращаюсь к акциям.*

Настраиваю тестовые акции для разных кейсов и начинаю отлаживать логику акции.

Одновременно может быть несколько активных акций со схожими параметрами. Нужно чтобы срабатывала наиболее выгодная для покупателя. Вот эту логику и впиливаю в процессинг.

*Собираю релиз и накатываю в тестовое окружение.*

### Go: Сервис ЭЛО

*Осталось немного рабочего времени, а от акций уже устал. Переключаюсь на этот проект.*

Накидал структуру и функции для работы с электронным табло. Подцепил вывод фиксированного числа к событиям сервера Elo. Все заработало, но коннект отвалился и с концами...

Начал разбираться, оказалось что-то накосякали при монтаже тестового стенда и мне дали IP от ЭЛО БОЕВОГО магазина o_O. Придется ждать завтра, когда инженеры исправят конфиги тестового стенда.

---

## 07.04.2021, среда, 06:00 - 18:00

### Flutter: Gallery app

*Желаю добрейшего утра дежурным... Кофе и в код...*

Тестировать приложение неудобно, поскольку в API бесплатно доступно только 50 запросов в час. Поэтому я решил добавить ещё один провайдер - SamplesProvider. В провайдре уже прописаны все готовые ответы и на все необходимые запросы. Прописываю новый провайдер в репозитории и получаю бесконечное количество тестовых запросов.

Есть одно НО! Возвращается всегда одинаковое количество объектов в ответе и неудобно тестить длинные и короткие списки. Поэтому сделал рандомное определение количества объектов в ответе на запрос. Причем для разных списков разная вероятность получения максимального количества на странице (чтобы сработала подгрузка новой "порции").

Испробовать решил на новом виджете для вывода списка фотографий, который поддерживает подгрузку фото при скролле, а так же обновление свайпом вниз.

*Запускаю билд, ставлю на тестовый смартфон и иду хвалиться коллегам за чашкой кофе.*

### 1С: Акция на доставку заказов

Последняя часть бизнес-логики акции - это этапное срабатывание акции (под которую ранее я создавал таблички, а в процессинге делал чтение и запись для них). В корзине и при оформлении заказа проверяются выполнение условий акции, а при оплате применяется скидка.

Для процессинга это два разных запроса, а значит в одном (при оформлении заказа) делаю проверку условий и запись в таблицу, если условия выполнены. А в другом запросе проверяю по таблице выполнились ли условия и применяю скидку.

*Отлаживаюсь и выкатываю изменения в тестовое окружение.*

### Go: Сервис ЭЛО

Инженеры поправили конфиги. Подключение к табло есть, но оно ничего не выводит. Игнорирует мои байтики, которые я засылаю в tcp-соединение. Инструкции нет, специалист по ЭЛО в отпуске. Отложим общение с табло до следующей недели и займёмся архитектурой сервиса.

Нашёл на GitHub проект по видео того самого блогера-программиста (писал о нём выше). Посмотрел и осознал наконец как на Go строится чистая архитектура.

---

## 08.04.2021, четверг, 06:00 - 18:00

### Flutter: Gallery app

*Уже привычное утро, кофе, Flutter.*

Во всех виджетах со списками фото нужно добавить открытие экрана с подробностями о фотографи. Все виджеты уже есть, нужно просто вызвать нужные функции. Что я и делаю.

Далее по ТЗ должен быть красивый индикатор загрузки. Но в данном спринте я запланировал реализовывать только функционал. Поэтому я делаю виджет-заглушку ProgressIndicator. Красивости будут позже, а пока вставляю его использование во всех остальных виджетах вместо стандартного CircularProgressIndicator. Только слегка кастомизировал его, чтобы видно было, что не стандартный.

Делаю Pull to refresh во всех виджетах фото типа List и Grid.

*Сборка, тест, кофе.*

### 1С: Акция на доставку заказов

Готовлю новый релиз, чтобы раскатить на все сервера. Провожу тесты на стейдже. Выкатываю в прод, мониторю, все ок.

Прогоняем несколько "тестовых" боевых заказов (заказы в новой логике, доступные только тестировщикам). Естественно вылезают всякие интеграционные косяки. Исправляем и проводим ещё несколько тестов.

*В целом все заработало, нужно только слегка подчистить...*

### Go: Сервис ЭЛО

Переписал код работы с сервером ЭЛО: в отдельный пакет вынес работу с TCP (как расширение стандартного пакета), в другом пакете оформил сервер TCP для работы с учётом специфики ЭЛО-сервиса. И ещё один handler-пакет для обработки сообщений от сервера.

Запустил тест - работает.

Идём дальше, нужно где то хранить бизнес логику сервиса. Для этого создаю заготовку пакета, в котором есть парочка структур и функции работы с Репозиторием.

Собираем все вместе в функции запуска RunApp и тестируем.

*В итоге первоначальную кучу текстового кода я переписал в чистой архитектуре. И я понял как дальше мне писать сервис.*

---

## 09.04.2021, пятница, 11:00 - 18:00

### 1С: Акция на доставку заказов

Привожу в порядок запросы, подчищаю код и убираю всякие интеграционные "затычки". Включаю дополнительные проверки, отключенные на этапе тестирования (проверка дублирующихся запросов, например).

### Go: Сервис ЭЛО

Начинаем обогащать сервис полезностями. В первую очередь - логи. Импортируем пакет logrus, расширяем его и заменяем логирование в проекте на собственный логгер.

На очереди конфиги. Viper - импортируем пакет и пишем модуль для инициализации пакета: Из констант заполняем самые важные параметры, затем из файла конфига .yml парсим параметры, а потом из переменных окружения заполняем оставшиеся (логины, явки, пароли). При запуске сервиса передаём имя файла конфига, заменяем хардкод на параметры из модуля config.

Запускаю - все работает.

---

# Неделя третья

## 12.04.2021, понедельник, 10:00 - 18:00

### 1С: Акция на доставку заказов

Иногда стали возникать непонятные задержки в расчетах. Именно в запросах к БД. Надо разобраться.

Расширил метрики запросов. Добавил замеры времени выполнения запросов на стороне SQL сервера.

*Прогнал тексты на stage , накатил на один сервер. Собираю метрики, ждём пару дней.*

### Go: Сервис ЭЛО

Пора впилить API в сервис. Импорт пакета gin. В пакете server/api описываем структуру для работы с http-сервером.

delivery/api - пишем заготовку для хендлеров и функцию инициализации структуры.

В функции запуска сервиса прописываем инициализацию api и запуск в отдельной горутине.

А ещё добавил кода для нормального завершения работы сервиса и закрытия всех соединений.

---

## 13.04.2021, вторник, 06:00 - 18:00

### Flutter: Gallery app

*Утро, 6, кофе.*

По заданию в случае ошибки нужно показывать сообщение с ошибкой. Оформляю в виде виджета ErrorWidget и вставляю в SearchScreen.

После чего решил, что все кнопки пора тоже вытащить в отдельный виджет - ButtonWidget.

Остался самый большой скрин - авторизация. Для авторизации в сервисе [Unsplash.com](http://unsplash.com/) нужно перейти по ссылке и заставить пользователя ввести логин/пароль. Затем API перенаправит на страничку с токеном, который уже можно использовать для запросов (OAuth-авторизация).

Для этого в класс провайдера добавляю метод проверки авторизации и выполнения запроса на авторизацию.

Создаю новый скрин LoginScreen, а в качестве основного виджета - WebView. В виджете обрабатываю события обновления данных и ловлю нужный URL (по RegEx шаблону) после перенаправления и запускаю авторизацию в провайдере.

Скрин готов, теперь нужно переделать главный экран. В декларативную навигацию прописываем новый путь, а при обновлении состояния главного экрана проверяем, если пользователь не авторизован - отрисовываем кнопку "Login". По нажатию на кнопку навигация открывает экран авторизации. А при успешной авторизации возвращаемся к главному экрану.

Попутно переписываю репозиторий на singleton, чтобы умел сохранять признаки авторизации.

На этом функциональная часть проекта полностью готова. Осталось привести в соответствие дизайну.

*Собираю проект и ставлю на тестовую мобилку. Иду пить кофе и тестировать.*

### Go: Сервис ЭЛО

Оказалось что нет четких знаний о том как работать с табло ЭЛО. Есть результаты сниффера сетевых пакетов. В целом структура сообщений понятна, методом научного подбора вычислили функцию расчета контрольных байтов сообщения (src16-ma...).

Далее кодим на коленке. Описываю структуру EloDisplay. Метод для отображения номера очереди - фиксированное значение по слайсу байт отобразить получилось. Для отображения динамического значения нужно вычислять контрольные байты.

Оказалось что пакетов на go для вычисления src16 нужного формата не нашел, но есть похожий. Методом гуглежа на Википедии нашел параметры, которые необходимы для вычисления. Проставил в пакет и все завелась. На дисплее отображается нужное число.

Тот же сниффер подсказал как можно помогать дисплеем, посылая слайс байт на включение и выключение светодиодов.

На очереди кнопка вызова покупателя. Понимаю соединение и получаю байты при нажатии на кнопку. Но на ней есть дисплей для отображения вызванного номера очереди. Документации нет, сниффа тоже. Пробую заслать байты тем же способом что и в табло. И получилось.

Собираю сервис для демонстрации. Несколько горутин для двух табло и кнопки: в каждой своей счётчик очереди с разными интервалами изменения. Одна из них ещё и заставляет моргать табло после изменения номера.

---

## 14.04.2021, среда, 06:00 - 18:00

### Go: Сервис ЭЛО

Последний функционал которого ещё нет в моей чистой архитектуре - печать на принтере ЭЛО.

Добавляю структуру TcpClient и прописываю ее взаимодействие с сервером.

Создаю PrinterService для отправки команды печати на сервер через TcpClient. Прописываю инициализацию созданных структур.

И запускаю тестовую печать. Все работает.

---

# Итоги

Спринт завершён и я уложился в сроки. Конечно же, помимо этих проектов было много другой работы: разборки с проблемами и ошибками, супер срочные мелкие задачи “напятьминут”, совещания/стендапы/митинги/встречи. 

## Flutter & Dart: Gallery app for unsplash.com

Приложение Gallery app готово. Хоть оно и не совсем соответствует дизайну, я не планирую дальнейшую его разработку. Моей целью было реализовать функциональную часть приложения, что я и выполнил. Сдавать “дипломную работу” я не планирую, поскольку курс по Flutter у организаторов не удался и у меня нет чувства долга перед этим курсом.

Этот проект помог мне уложить в сознании как строить архитектуру своего приложения (а это всегда тревожит меня больше всего) и отработать навыки работы с виджетами, а также различными пакетами (Dio, например). А полученные знания я планирую применить в миграции боевого проекта с Kotlin на Flutter.

## 1С: Предприятие 8: Акция на доставку заказов

Акция написана в срок и готова к старту в любой момент времени. Параметры позволяют гибко настраивать различные условия как одной, так и сразу нескольких акций. 

Кроме того, новый механизм расчета акций можно развивать и использовать в дальнейшем и для других типов акций.

## Go: Сервис электронной очереди

Мне удалось в короткие сроки реализовать не только замену существующей электронной очереди, но и реализовать в сервисе ряд дополнительных функций:

- Возможность использования нескольких очередей;
- Разделение настроек для каждого подключаемого оборудования;
- Использование шаблонов для печати талончиков;
- Сохранение состояния очереди при перезапуске сервисов;
- Хранение информации о выданных талончиках.

Эти функции позволят значительно расширить функционал текущей электронной очереди.

Проект позволил мне в бою попробовать свои силы в Go. Конечно я освоил далеко не все, но я осознал идеологию этого языка и смогу без проблем читать проекты на нем.
